package org.dba.ui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dba.ui.QuadristateButtonModel.State;

public class DefaultCheckboxTreeCellRenderer extends JPanel implements CheckboxTreeCellRenderer {

	protected QuadristateCheckbox checkBox = new QuadristateCheckbox();
	Log log = LogFactory.getLog(getClass());
	protected DefaultTreeCellRenderer label = new DefaultTreeCellRenderer();
	int maxWidth = 0;

	public DefaultCheckboxTreeCellRenderer() {
		this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
		add(this.checkBox);
		add(this.label);
		this.checkBox.setBackground(UIManager.getColor("Tree.textBackground"));
		this.setBackground(UIManager.getColor("Tree.textBackground"));
	}

	@Override
	public Dimension getPreferredSize() {
		Dimension d_check = this.checkBox.getPreferredSize();
		Dimension d_label = this.label.getPreferredSize();
		return new Dimension(d_check.width + d_label.width, (d_check.height < d_label.height ? d_label.height + 10 : d_check.height + 10));
	}

	/**
	 * Decorates this renderer based on the passed in components.
	 */
	public Component getTreeCellRendererComponent(JTree tree, Object object, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
		/*
		 * most of the rendering is delegated to the wrapped
		 * DefaultTreeCellRenderer, the rest depends on the TreeCheckingModel
		 */
		this.label.getTreeCellRendererComponent(tree, object, selected, expanded, leaf, row, hasFocus);
		if (tree instanceof CheckboxTree) {
			TreeCheckingModel checkingModel = ((CheckboxTree) tree).getCheckingModel();
			TreePath path = tree.getPathForRow(row);
			this.checkBox.setEnabled(checkingModel.isPathEnabled(path));
			boolean checked = checkingModel.isPathChecked(path);
			boolean greyed = checkingModel.isPathGreyed(path);
			if (checked && !greyed) {
				this.checkBox.setState(State.CHECKED);
			}
			if (!checked && greyed) {
				this.checkBox.setState(State.GREY_UNCHECKED);
			}
			if (checked && greyed) {
				this.checkBox.setState(State.GREY_CHECKED);
			}
			if (!checked && !greyed) {
				this.checkBox.setState(State.UNCHECKED);
			}
		}
		return this;
	}

	/**
	 * Checks if the (x,y) coordinates are on the Checkbox.
	 * 
	 * @return boolean
	 * @param x
	 * @param y
	 */
	public boolean isOnHotspot(int x, int y) {
		// TODO: alternativa (ma funge???)
		// return this.checkBox.contains(x, y);
		return (this.checkBox.getBounds().contains(x, y));
	}

	/**
	 * Loads an ImageIcon from the file iconFile, searching it in the
	 * classpath.Guarda un po'
	 */
	protected static ImageIcon loadIcon(String iconFile) {
		try {
			return new ImageIcon(DefaultCheckboxTreeCellRenderer.class.getClassLoader().getResource(iconFile));
		} catch (NullPointerException npe) { // did not find the resource
			return null;
		}
	}

	@Override
	public void setBackground(Color color) {
		if (color instanceof ColorUIResource) {
			color = null;
		}
		super.setBackground(color);
	}

	/**
	 * Sets the icon used to represent non-leaf nodes that are expanded.
	 */
	public void setOpenIcon(Icon newIcon) {
		this.label.setOpenIcon(newIcon);
	}

	/**
	 * Sets the icon used to represent non-leaf nodes that are not expanded.
	 */
	public void setClosedIcon(Icon newIcon) {
		this.label.setClosedIcon(newIcon);
	}

	/**
	 * Sets the icon used to represent leaf nodes.
	 */
	public void setLeafIcon(Icon newIcon) {
		this.label.setLeafIcon(newIcon);
	}

	public void setIcon(Icon newIcon) {
		this.label.setIcon(newIcon);
	}

	public void setText(String name) {
		this.label.setText(name);
	}

	public void setFColor(Color c, String name) {
		synchronized (label) {
			String __c = "";
			if (c == Color.RED) {
				__c = "red";
			} else if (c == Color.WHITE) {
				__c = "white";
			}
			String _c = "<html><font color=" + __c + ">" + name + "</font></html>";

			FontMetrics fm = getToolkit().getFontMetrics(getFont());
			BufferedReader br = new BufferedReader(new StringReader(name));
			String line;
			try {
				while ((line = br.readLine()) != null) {
					int width = SwingUtilities.computeStringWidth(fm, line);
					if (maxWidth < width) {
						maxWidth = width;
						//log.info("maxWidth="+maxWidth);
					}
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
			this.label.setPreferredSize(new Dimension(maxWidth + 20, 20));
			maxWidth = 0;
			this.label.setText(_c);
		}
	}

}